package net.cyan.thunwind.dao;

import net.cyan.commons.aop.proxy.AbstractMethodProxy;
import net.cyan.commons.util.*;
import net.cyan.thunwind.annotation.*;

import java.lang.reflect.Method;

/**
 * 
 * @author camel
 * @date 2008-11-20
 */
public class SQLUpdateGenerator implements DaoContentGenerator
{
    public SQLUpdateGenerator()
    {
    }

    public boolean generateContent(Method method, String[] parameterNames, Class c, StringBuilder buffer)
    {
        SQLStruct sqlStruct = getSQLStruct(method);
        if (sqlStruct != null)
        {
            Class returnType = method.getReturnType();

            if (returnType != void.class)
                buffer.append("Integer temp=new Integer(");

            buffer.append("handler$$.executeSql").append("(\"").append(StringUtils.escapeString(sqlStruct.getSql()))
                    .append("\",");

            if (sqlStruct.isNativeSql() != null)
                buffer.append(sqlStruct.isNativeSql()).append(",");

            if (parameterNames.length > 0)
            {
                Class[] parameterTypes = method.getParameterTypes();
                buffer.append("new Object[]{");
                for (int i = 0; i < parameterNames.length; i++)
                {
                    if (i > 0)
                        buffer.append(",");
                    Class parameterType = parameterTypes[i];
                    if (parameterType.isPrimitive())
                        AbstractMethodProxy.generateBox(buffer, parameterNames[i], parameterType);
                    else
                        buffer.append(parameterNames[i]);
                }
                buffer.append("}");
            }
            else
            {
                buffer.append("(Object[])null");
            }

            buffer.append(")");

            if (returnType != void.class)
                buffer.append(")");
            buffer.append(";\n");

            if (returnType != void.class)
            {
                String typeName = BeanUtils.getClassName(returnType);

                buffer.append(typeName).append(" $result=");
                AbstractMethodProxy.generateCast(buffer, "temp", returnType);
                buffer.append(";");
            }

            return true;
        }

        return false;
    }

    protected SQLStruct getSQLStruct(Method method)
    {
        SQLUpdate sqlUpdate = method.getAnnotation(SQLUpdate.class);
        NativeSql nativeSql = method.getAnnotation(NativeSql.class);

        return sqlUpdate != null ? new SQLStruct(sqlUpdate.value(), nativeSql == null ? null : nativeSql.value()) :
                null;
    }
}
